package DAO;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JOptionPane;

import connection.ConnectionManager;

import modelo.Estadio;
import modelo.Localizacao;

public class EstadioDAOImp implements EstadioDAO {
	/**
	 * metodos para o banco de dados
	 */
	/**
	 * metodo de inserir o estadio
	 */
	private final String INSERT = "INSERT INTO Estadio(id_localizacao, cadeiras_camarote, cadeiras_geral , nome) VALUES (?,?,?,?)";
	/**
	 * metodo para alterar o estadio
	 */
	private final String UPDATE = "UPDATE Estadio SET id_localizacao = ?, cadeiras_camarote = ?, cadeiras_geral = ? , nome = ? WHERE id_estadio = ?";
	/**
	 * metodo para deletar um estadio
	 */
	private final String DELETE = "DELETE from Estadio WHERE idEstadio = ?";
	/**
	 * metodo para selecionar todos os estadios
	 */
	private final String ALL = "SELECT id_estadio, id_localizacao, cadeiras_camarote, cadeiras_geral , nome FROM Estadio";
	/**
	 * metodo para mostrar estadio pelo nome inteiro ou abreviado
	 */
	private final String LIKE = "SELECT id_estadio, id_localizacao, cadeiras_camarote, cadeiras_geral , nome FROM Estadio where nome = ?";
	/**
	 * metodo para mostrar estadio pelo identificador
	 */
	private final String ID = "SELECT id_estadio,nome, id_localizacao, cadeiras_camarote, cadeiras_geral , nome FROM Estadio where id_estadio = ?";
	
	/**
	 * variaveis de conexao com o banco
	 */
	private ConnectionManager connectionManager;
	private static Connection connection;
	
	EstadioDAOImp(){
		this.openConnection();
	}

	@Override
	/**
	 * Metodo para salvar um estadio
	 */
	public Estadio salvar(Estadio e) {
		try {
			/** crie uma instancia de PreparedStatement 
			 *passe para ela a instrucao para realizar alteracoes em uma registro do banco
			*/
			PreparedStatement ps = null;

			ps = connection.prepareStatement(INSERT);
			
			ps.setObject(1, e.getLocalizacao().getIdLocalizacao());
			ps.setObject(2, e.getCadeirasCamarotes());
			ps.setObject(3, e.getCadeiraGeral());
			ps.setObject(4, e.getNome());
			
			ps.executeUpdate();
			
		} catch (SQLException ex) {
			Logger.getLogger(EstadioDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return e;
	
	}

	@Override
	/**
	 * metodo para alterar um estadio 
	 */
	public void alterar(Estadio e) {
		PreparedStatement ps = null;
		try {
			/** crie uma instancia de PreparedStatement 
			*passe para ela a instrucao para realizar alteracoes em uma registro do banco
			*/ 
			ps = connection.prepareStatement(UPDATE);
			
			ps.setObject(1, e.getLocalizacao().getIdLocalizacao());
			ps.setObject(2, e.getCadeirasCamarotes());
			ps.setObject(3, e.getCadeiraGeral());
			ps.setObject(4, e.getNome());
			ps.setObject(5, e.getIdEstadio());
			

			
			ps.executeUpdate();

		} catch (SQLException ex) {
			Logger.getLogger(EstadioDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}

	}

	@Override
	/**
	 * metodo para deletar um estadio pelo id
	 */
	public void deletar(Estadio e) {
		try {
			/** passe para o PreparedStatement o valor do id que deve ser excluido do banco de dados 
			 *
			*/
			
			PreparedStatement ps = null;
			ps = connection.prepareStatement(DELETE);
		 
			ps.setObject(1, e.getIdEstadio());
			
			ps.executeUpdate();

		} catch (SQLException ex) {
			Logger.getLogger(EstadioDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}

	}

	@Override
	/**
	 * metodo para mostrar todo os estadios em uma lista
	 */
	public List<Estadio> findAll() {
		List<Estadio> estadios = new ArrayList<Estadio>();
		LocalizacaoDAO local= DAOFactory.getLocalizacaoDAO();
		List<Localizacao> locais = new ArrayList<Localizacao>();
		try {
			PreparedStatement ps = null;
			ResultSet rs = null;
			ps = connection.prepareStatement(ALL);
			
			/** Obtenha uma instancia de resultset*/
			rs = ps.executeQuery();
			
			while (rs.next()) {
				locais = local.buscaLocalizacaoPorId(rs.getInt("id_localizacao"));
				local.openConnection();
				Estadio estadio = new Estadio();
				estadio.setIdEstadio(rs.getInt("id_estadio"));
				estadio.setNome(rs.getString("nome"));
				estadio.setCadeiraGeral(rs.getInt("cadeiras_geral"));
				estadio.setCadeirasCamarotes(rs.getInt("cadeiras_camarote"));
				
				estadio.setLocalizacao(locais.get(0));
				estadios.add(estadio);
			}

		} catch (SQLException ex) {
			Logger.getLogger(EstadioDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return estadios;
	}

	@Override
	/**
	 * testando se a conexao com o banco esta fechada
	 */
	public boolean isConnectionClose() {
		try {
			return connection.isClosed();
		} catch (SQLException ex) {
			return false;
		}
	}

	@Override
	/**
	 * abrindo conexao com banco de dados
	 */
	public void openConnection() {
		if ( connectionManager == null ) {
			connectionManager = ConnectionManager.getInstance();
		}
		
		if ( connection == null) {
			connection = connectionManager.getConnection();
		}
		
		if ( isConnectionClose() ) {
			connection = connectionManager.getConnection();
		}
		
	}
	
	@Override
	/**
	 * fechando conexao com o banco
	 */
	public void closeConnection() {
		if ( connection != null && connectionManager != null) {
			if ( ! this.isConnectionClose() ) {
				connectionManager.closeConnection(connection);
			}
		}
		
	}

	@Override
	/**
	 * metodo para buscar um estadio por nome
	 */
	public List<Estadio> buscaEstadioPorNome(Estadio estadio) {
		List<Estadio> estadios = new ArrayList<Estadio>();
		LocalizacaoDAO local= DAOFactory.getLocalizacaoDAO();
		List<Localizacao> locais = new ArrayList<Localizacao>();
		
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			ps = connection.prepareStatement(LIKE);
			/**
			 *  informe o parmetro para instrucao like
			 */
			ps.setObject(1, estadio.getNome());
		
			rs = ps.executeQuery();

			while (rs.next()) {
				locais = local.buscaLocalizacaoPorId(rs.getInt("id_localizacao"));
				estadio.setIdEstadio(rs.getInt("id_estadio"));
				estadio.setNome(rs.getString("nome"));
				estadio.setCadeiraGeral(rs.getInt("cadeiras_geral"));
				estadio.setCadeirasCamarotes(rs.getInt("cadeiras_camarote"));
				
				estadio.setLocalizacao(locais.get(0));
				estadios.add(estadio);
				/**
				 *  crie uma instancia de cidade com os dados
				 * obtidos do banco e adicione a lista de cidades
				*/
				
			}

		} catch (SQLException ex) {
			Logger.getLogger(EstadioDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
	
		return estadios;
	}

	@Override
	/**
	 * metodo para buscar um estadio por ID
	 */
	public List<Estadio> buscaEstadioPorId(int idEstadio) {
		List<Estadio> estadios = new ArrayList<Estadio>();
		LocalizacaoDAO local= DAOFactory.getLocalizacaoDAO();
		List<Localizacao> locais = new ArrayList<Localizacao>();
		Estadio estadio = new Estadio();
		
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			ps = connection.prepareStatement(ID);
			/**
			 *  informe o parmetro para instrucao ID
			 */
			ps.setObject(1, idEstadio);
		
			rs = ps.executeQuery();

			while (rs.next()) {
				
				estadio.setIdEstadio(rs.getInt("id_estadio"));
				estadio.setNome(rs.getString("nome"));
				estadio.setCadeiraGeral(rs.getInt("cadeiras_geral"));
				estadio.setCadeirasCamarotes(rs.getInt("cadeiras_camarote"));
				locais = local.buscaLocalizacaoPorId(rs.getInt("id_localizacao"));
				estadio.setLocalizacao(locais.get(0));
				estadios.add(estadio);
				/**
				 * 5 crie uma instancia de cidade com os dados
				 * obtidos do banco e adicione a lista de cidades
				*/
			}
		} catch (SQLException ex) {
			Logger.getLogger(EstadioDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		}
		
			return estadios;
}

}
